(function ( exports ) {
    //region Xrm2011ContractsValue

    function Xrm2011ContractsValue ( value ) {
        COSA.XrmValue.call(this, value);
    }

    COSA.Util.deriveOverride(COSA.XrmValue, Xrm2011ContractsValue, {
        type: '',
        namespace: 'http://schemas.microsoft.com/xrm/2011/Contracts',
        requireTypeDef: true
    });

    //endregion Xrm2011ContractsValue

    //region Money

    /**
     * Money
     * @param {number} value Money value
     * @param {string} formattedValue Formatted value
     * @memberOf COSA
     * @constructor XrmMoney
     */
    function XrmMoney ( value, formattedValue ) {
        Xrm2011ContractsValue.call(this, value );
        this.formattedValue = formattedValue;
    }

    COSA.Util.deriveOverride(Xrm2011ContractsValue, XrmMoney, {
        type: 'Money',
        getTemplate: function ( sc, ltr ) {
            return [{
                tag: ltr.tag('Value'),
                val: this.value
            }];
        },
        validate: function () {
            (new COSA.ValueChecker(this.value))
                .defined()
                .typeOf('number');
        },
        deserialize: function ( node ) {
            this.value = parseFloat(node.node('Value'));
        }
    });

    //endregion Money

    //region OptionSetValue

    /**
     * OptionSetValue
     * @param {number} value OptionSetValue
     * @param {string} formattedValue OptionSet formatted value
     * @prop {number} value OptionSetValue
     * @prop {string} formattedValue Formatted OptionSet value
     * @memberOf COSA
     * @constructor OptionSetValue
     */
    function OptionSetValue ( value, formattedValue ) {
        Xrm2011ContractsValue.call(this, value);
        this.formattedValue = formattedValue;
    }

    COSA.Util.deriveOverride(Xrm2011ContractsValue, OptionSetValue, {
        type: 'OptionSetValue',
        requireTypeDef:true,
        getTemplate: function ( sc, tgr ) {
            return [{
                tag: tgr.tag('Value'),
                val: this.value
            }];
        },
        validate: function () {
            (new COSA.ValueChecker(this.value))
                .defined()
                .int();
        }
    });

    //endregion OptionSetValue

    exports.XrmMoney = XrmMoney;
    exports.OptionSetValue = OptionSetValue;
})(COSA);
